// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <pollux/vector/base_vector.h>

namespace kumo::pollux {
    struct EncodedVectorCopyOptions {
        /// The memory pool used to create new target vector.  If target is set, the
        /// memory pool must be the same as this one.
        memory::MemoryPool *pool;

        /// Whether we can reuse any part from the source vector in target.  If this
        /// is true, the source and target must have the same memory pool.
        bool reuseSource;

        /// How many nested rows in ARRAY or MAP need to be referenced in order to
        /// avoid a compaction on it.
        double compactNestedThreshold = 0.5;
    };

    /// Copy the vector while try to preserve the encoding on `target' (with
    /// exceptions listed below), mainly to reduce the memory usage of `target'.  If
    /// `target' is nullptr, preserve the encoding on `source'.
    ///
    /// `ranges' should not have any overlaps in target (overlaps in source are
    /// allowed).  If target ranges exceeds the old target vector size, the vector
    /// will be automatically extended; in this case, the target ranges must cover
    /// all the missing part from the old vector.
    ///
    /// In the following cases we do not preserve the exact encoding on `target':
    /// - We merge multiple adjacent layers of dictionary and constant wrappers into
    ///   one.
    /// - When the values type size in dictionary is no larger than the index type,
    ///   we flatten the vector to save memory.
    /// - When `target' is constant, we convert it to dictionary to allow different
    ///   values in `source'.
    /// - When `target' is flat ROW, MAP, or ARRAY, and `source' is constant or
    ///   dictionary encoded, the result will be dictionary encoded, to avoid
    ///   flattening the child vectors.  Once the target becomes dictionary, it can
    ///   stay that way and we can keep adding new content to it while keeping the
    ///   encoding, this is a typical use case for encoding preserved merging.
    void encodedVectorCopy(
        const EncodedVectorCopyOptions &options,
        const VectorPtr &source,
        const melon::Range<const BaseVector::CopyRange *> &ranges,
        VectorPtr &target);
} // namespace kumo::pollux
